package scuba.DiveBuddy.Class;

import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.LocalTime;
import scuba.DiveBuddy.Core.Toolbelt;
import scuba.DiveBuddy.Core.Triple;
import scuba.DiveBuddy.Core.Tuple;

import java.util.Date;

/**
 * @author Alex Anderson
 * @version 1.0
 * @since {28/02/14}
 */
public class LogPageSanitiser {

    //<editor-fold desc="----> Singleton">
    private static LogPageSanitiser _instance;
    public static LogPageSanitiser getInstance() {
        if(_instance == null)
            _instance = new LogPageSanitiser();

        return _instance;
    }

    public static void Reset() {
        LogPageSanitiser._instance = new LogPageSanitiser();
    }
    //</editor-fold>

    /**
     * the Sanitisers Job is to provide a framework for input checking.
     * E.g. checking to see if the depth fits a profile, and telling us to prompt the user to
     *  check if the input is correct.
     */

    // ----> Attributes
    private boolean isDepthSanitisedAndSet;
    private boolean isStartAirSanitisedAndSet;
    private boolean isEndAirSanitisedAndSet;
    private boolean isDateSanitisedAndSet;
    private boolean isTimeInSanitisedAndSet;
    private boolean isTimeOutSanitisedAndSet;


    // ----> Constructor
    public LogPageSanitiser() {
        this.isDepthSanitisedAndSet = false;
        this.isStartAirSanitisedAndSet = false;
        this.isEndAirSanitisedAndSet = false;
        this.isTimeInSanitisedAndSet = false;
        this.isTimeOutSanitisedAndSet = false;
    }

    // ----> Methods
    public boolean isDepthSanitisedAndSet() { return this.isDepthSanitisedAndSet; }
    public boolean isStartAirSanitisedAndSet() { return this.isStartAirSanitisedAndSet; }
    public boolean isEndAirSanitisedAndSet() { return this.isEndAirSanitisedAndSet; }
    public boolean isTimeInSanitisedAndSet() { return this.isTimeInSanitisedAndSet; }
    public boolean isTimeOutSanitisedAndSet() { return this.isTimeOutSanitisedAndSet; }
    public boolean isDateSanitisedAndSet() { return this.isDateSanitisedAndSet; }

    public Tuple<Boolean, String> isComplete() {

        if(!isDepthSanitisedAndSet)
            return new Tuple<Boolean, String>(false, "Depth has not been satisfied");

        if(!isStartAirSanitisedAndSet)
            return new Tuple<Boolean, String>(false, "Start Air has not been satisfied");

        if(!isEndAirSanitisedAndSet)
            return new Tuple<Boolean, String>(false, "End Air has not been satisfied");

        if(!isTimeInSanitisedAndSet)
            return new Tuple<Boolean, String>(false, "Time In has not been satisfied");

        if(!isTimeOutSanitisedAndSet)
            return new Tuple<Boolean, String>(false, "Time Out has not been satisfied");

        //if(!isDateSanitisedAndSet)
            //return new Tuple<Boolean, String>(false, "Date has not been satisfied");

        return new Tuple<Boolean, String>(true, "All Ok");
    }

    public Boolean sanitiseDate(LocalDate date) {
       //todo:
        return false;
    }

    public Boolean sanitiseTimeIn(LocalTime in) {
        LocalTime out = LogEntries.getCurrent().getTimeOut();
        if(in.isBefore(out) || in.compareTo(out) == 0) {
            this.isTimeInSanitisedAndSet = true;
            return true;
        }

        this.isTimeInSanitisedAndSet = false;
        return false;
    }
    public Boolean sanitiseTimeOut(LocalTime out) {
        LocalTime in = LogEntries.getCurrent().getTimeIn();
        if(out.isAfter(in)) {
            this.isTimeOutSanitisedAndSet = true;
            return true;
        }

        this.isTimeOutSanitisedAndSet = false;
        return false;
    }

    public Triple<Boolean, Float, String> sanitiseDepth(String depth) {
        Tuple<Boolean, Float> result = Toolbelt.Toolkit.getFloatFromString(depth, 0);
        this.isDepthSanitisedAndSet = result.x;

        if(!result.x) {
            //Shouldn't ever get this
            return new Triple<Boolean, Float, String>(result.x, result.y, "A Valid float was not entered for depth");
        }

        //todo: look at history and decide if this is "acceptable"
        //Third Param is a Reason
        return new Triple<Boolean, Float, String>(result.x, result.y, "");
    }

    public Triple<Boolean, Float, String> sanitiseStartAir(String air) {
        Tuple<Boolean, Float> result = Toolbelt.Toolkit.getFloatFromString(air, 0);
        isStartAirSanitisedAndSet = result.x;

        if(!result.x) {
            //Shouldn't ever get this
            return new Triple<Boolean, Float, String>(result.x, result.y, "A Valid float was not entered for depth");
        }

        //todo: look at history and decide if this is "acceptable"
        //Third Param is a Reason
        return new Triple<Boolean, Float, String>(result.x, result.y, "");
    }
    public Triple<Boolean, Float, String> sanitiseEndAir(String air) {
        Tuple<Boolean, Float> result = Toolbelt.Toolkit.getFloatFromString(air, 0);
        isEndAirSanitisedAndSet = result.x;

        if(!result.x) {
            //Shouldn't ever get this
            return new Triple<Boolean, Float, String>(result.x, result.y, "A Valid float was not entered for depth");
        }

        //todo: look at history and decide if this is "acceptable"
        //Third Param is a Reason
        return new Triple<Boolean, Float, String>(result.x, result.y, "");
    }
}
